#!/usr/bin/env bash
# -----------------------------------------------------------------------------
# Environment Variable Prerequisites
#
#   EGL_HOME      Point to the micro server home directory.
#
#   EGL_ENV       Should be DEV/CI/SIT/UAT/STR/PRE/PRD.
#
#   JAVA_HOME       Must point at your Java Development Kit installation.
#
#   JAVA_OPTS       (Optional) Java runtime options used when any command
#                   is executed.
# -----------------------------------------------------------------------------

echo " /**                                             "
echo " | **                                            "
echo " | **  /******  /******/****   /******  /******* "
echo " | ** /**__  **| **_  **_  ** /**__  **| **__  **"
echo " | **| ********| ** \ ** \ **| **  \ **| **  \ **"
echo " | **| **_____/| ** | ** | **| **  | **| **  | **"
echo " | **|  *******| ** | ** | **|  ******/| **  | **"
echo " |__/ \_______/|__/ |__/ |__/ \______/ |__/  |__/"

#function defined
gracefulShutdown(){
  PID=$1
  PORT=$(ss -anp 2>/dev/null|grep -w "${PID}" |grep -w "LISTEN" |awk '{print $5}'|awk -F ":" '{print $NF}')
  curl -X POST http://127.0.0.1:${PORT}/actuator/shutdown
  echo
  echo "The server [${PID}] will be graceful shutdown"
  for wi in {1..50}
  do
    echo -n "."
    num=`ps -p "${PID}" | grep "${PID}" | wc -l`
    if [ ${num} -ge 1 ]; then
      sleep 1s
    else
      break
    fi
  done
  echo
}

forceShutdown(){
  kill -9 $1
  for wi in {1..5}
  do
    echo -n "."
    sleep 1s
  done
  echo
}


eglShutdown(){
  EXIST_PID=$1
  gracefulShutdown ${EXIST_PID}
  num=`ps -p "${EXIST_PID}" | grep "${EXIST_PID}" | wc -l`
  if [ ${num} -ge 1 ]; then
    echo "The server [${EXIST_PID}] has not stoped yet, force shutdown it."
    forceShutdown ${EXIST_PID}
  else
    echo "The server [${EXIST_PID}] has graceful stoped."
  fi
}

# Executable jar of micro server
EGL_JAR=""

# Check environment variables
if [ -z "${EGL_HOME}" ]; then
  EGL_HOME="$(cd `dirname $0`;cd ..;pwd)"
fi
if [ -z "${EGL_JAR}" ]; then
  JARS_IN_HOME=$(ls ${EGL_HOME}/bms/*.jar)
  _i=0
  for JAR in $JARS_IN_HOME
  do
    _i=$((_i + 1))
    echo "Deploying ${JAR}...."
    if [ ${_i} -gt 1 ]; then
      echo "Can only have one start jar file in micro home $EGL_HOME"
      exit 1
    fi
    EGL_JAR=$JAR
  done
fi

# Get application ID
APPID=$(echo $EGL_HOME/bms |awk -F "/" '{print $NF}')
echo $APPID


if [ ! -f ${EGL_JAR} ]; then
  EGL_JAR=${EGL_HOME}/${EGL_JAR}
fi

if [ -z "${EGL_ENV}" ]; then
  echo "EGL_ENV environment variable not defined, value should be DEV/CI/SIT/UAT/STR/PRE/PRD."
  exit 1
fi
if [ -z "${JAVA_HOME}" ]; then
  JAVA_PATH=`which java 2>/dev/null`
  if [ "x${JAVA_PATH}" != "x" ]; then
    JAVA_HOME=`dirname $(dirname ${JAVA_PATH}) 2>/dev/null`
  fi
  if [ -z "${JAVA_HOME}" ]; then
    echo "JAVA_HOME environment variable not defined."
    exit 1
  fi
fi

# Set PID file
PID_FILE="${EGL_HOME}/bms/${APPID}.pid"

# Check if server is running
if [ -f "${PID_FILE}" ]; then
  EXIST_PID=`cat "${PID_FILE}"`
  num=`ps -p "${EXIST_PID}" | grep "${EXIST_PID}" | wc -l`
  if [ ${num} -ge 1 ]; then
    #echo "Can't start Micro Server server, an existing server[${EXIST_PID}] is running."
    #exit 1
    echo "An existing server[${EXIST_PID}] is running, starting to shutdown it, please wait for a monent."
    eglShutdown ${EXIST_PID}
  fi
fi

# Backup previous logs
LOG_DIR="${EGL_HOME}/logs/bms"
BACK_DIR="${EGL_HOME}/logs/backup/bms"
if [ ! -d "${BACK_DIR}" ]; then
  mkdir -p "${BACK_DIR}"
fi
TS=`date +%Y%m%d%H%M%S`
if [ -d "${LOG_DIR}" ]; then
  mv "${LOG_DIR}" "${BACK_DIR}/${APPID}_LOG_${TS}"
fi

# Log files
`mkdir -p "${LOG_DIR}"`
OUT_FILE="${LOG_DIR}/server.out"
ERR_FILE="${LOG_DIR}/server.err"
GC_FILE="${LOG_DIR}/server-gc.log"

# Set options for server starting
MEM_SIZE_MB="180"
MEM_OPTS="-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms${MEM_SIZE_MB}m -Xmx${MEM_SIZE_MB}m -Xmn256m -Xss256k -XX:SurvivorRatio=8"
GC_OPTS="-XX:+UseG1GC -XX:MaxGCPauseMillis=50 -verbose:gc -Xloggc:${GC_FILE} -XX:+PrintGCDateStamps -XX:+PrintGCDetails"
DEBUG_OPTS="-Xverify:none -XX:+HeapDumpOnOutOfMemoryError -XX:+UnlockCommercialFeatures -XX:+FlightRecorder"
DEBUG_OPTS="-XX:AutoBoxCacheMax=10000 -XX:+PrintCommandLineFlags ${DEBUG_OPTS}"
JAVA_OPTS="${JAVA_OPTS} ${MEM_OPTS} ${DEBUG_OPTS} ${GC_OPTS}"

CLASSPATH="."
#LIB_DIR="${EGL_HOME}/lib"
#if [ -d "$LIB_DIR" ]; then
#  for f in ${LIB_DIR}/*.jar
#  do
#    CLASSPATH="${CLASSPATH}:${f}"
#  done
#fi

EGL_NACOS_REG_ENABLED="-Degl.nacos.register-enabled=true"
if [ ! -z "${EGL_BATCH_ENABLED}" ]; then
  EGL_BATCH_ENABLE="-Degl.batch.enabled=${EGL_BATCH_ENABLED}"
  EGL_NACOS_REG_ENABLED="-Degl.nacos.register-enabled=false"
fi

if [ ! -z "${EGL_NACOS_ADDR}" ]; then
  EGL_NACOS_ADDR="-Degl.nacos.addr=${EGL_NACOS_ADDR} "
fi

if [ ! -z "${EGL_USABLE_IP}" ]; then
  EGL_USABLE_IP="-Degl.usable.ip=${EGL_USABLE_IP}"
fi
if [ ! -z "${EGL_NACOS_GROUP}" ]; then
  EGL_NACOS_GROUP="-Degl.nacos.group=${EGL_NACOS_GROUP}"
fi
if [ ! -z "${EGL_LOG_LEVEL}" ]; then
  EGL_LOG_LEVEL="-Degl.log.level=${EGL_LOG_LEVEL}"
fi

if [ ! -z "${EGL_APIDOC_ENABLED}" ]; then
  EGL_APIDOC_ENABLED="-Degl.apidoc.enabled=${EGL_APIDOC_ENABLED}"
fi

EGL_OPTS="-Degl.home=${EGL_HOME} ${EGL_NACOS_REG_ENABLED} ${EGL_NACOS_ADDR} ${EGL_NACOS_GROUP} ${EGL_USABLE_IP} ${EGL_LOG_LEVEL} -Degl.log.path=${LOG_DIR} ${EGL_BATCH_ENABLE} ${EGL_APIDOC_ENABLED}"
SPRING_OPTS_ACTIVE="--spring.profiles.active=${EGL_ENV}"
SPRING_OPTS="${SPRING_OPTS_ACTIVE}"

echo "--------------------------------------------------"
echo "Starting EGL Micro Server "
echo "--------------------------------------------------"
echo "EGL_HOME   : ${EGL_HOME}"
echo "EGL_ENV    : ${EGL_ENV}"
echo "EGL_JAR   : ${EGL_JAR}"
echo "EGL_OPTS : ${EGL_OPTS}"
echo "SPRING_OPTS : ${SPRING_OPTS}"
echo "LOG_DIR : ${LOG_DIR}"
echo "JAVA_HOME    : ${JAVA_HOME}"
echo "JAVA_OPTS    : ${JAVA_OPTS}"
echo "--------------------------------------------------"

startTm_s=$(date +%s)
# Start server
#RUN_CMD="${JAVA_HOME}/bin/java ${JAVA_OPTS} -cp ${CLASSPATH} ${EGL_OPTS} ${EGL_MAIN} ${SPRING_OPTS}"
RUN_CMD="${JAVA_HOME}/bin/java ${JAVA_OPTS} ${EGL_OPTS} -jar ${EGL_JAR} ${SPRING_OPTS}"
echo "Ready to run Micro Server with command: " >${OUT_FILE}
echo "${RUN_CMD}" >>${OUT_FILE}
nohup ${RUN_CMD} >>${OUT_FILE} 2>${ERR_FILE} &

# Save PID file
PID=$!
echo ${PID} >"${PID_FILE}"

# Waiting for server starting
echo -n "Waiting for server[${PID}] to start."
start_sec=0
max_sec=60
while [ ${start_sec} -lt ${max_sec} ] ; do
  num=`ss -anp 2>/dev/null | grep -w "${PID}" | grep -w "LISTEN" | wc -l`
  if [ ${num} -ge 1 ]; then
    endTm_s=$(date +%s)
    execTm=$((endTm_s-startTm_s))
    echo
    PORT=$(ss -anp 2>/dev/null|grep -w "${PID}" |grep -w "LISTEN" |awk '{print $5}'|awk -F ":" '{print $NF}')
    echo "Micro started on port(s): ${PORT}"
    echo "Started EGL Micro Application in ($execTm) seconds "
    exit 0
  fi
  echo -n "."
  min=`expr ${start_sec} + 1`
  sleep 1
done
echo "Server did not started in ${max_sec} seconds, please check log files."
exit 1